const glob = require('glob');
const fs = require('fs');
const chalk = require('chalk');
const archiver = require('archiver');
const path = require('path');
const copyDir = require('copy-dir');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const config = require('./../config.js');

module.exports = {
  entryFile: 'index.js',
  /**
   * 复制公共资源
   */
  copyComment() {
    const commentAsset = path.resolve(__dirname, '../../', 'app/assets');
    if (fs.existsSync(commentAsset)) {
      const entrys = config.entry || [];
      entrys.forEach((entry) => {
        copyDir(commentAsset, path.resolve(__dirname, '../../', `app/${entry}/assets`), () => {
          console.log('公共资源复制成功！');
        });
      });
    }
  },
  /**
   * 资源文件目录
   * @param {String} url 资源路径
   * @param {String} type 资源类型
   * @returns {String}
   */
  buildAssetsUrl(url, type) {
    let name = path.join(`assets/${type}/[name].[hash:7].[ext]`); // 默认资源目录
    // 业务模块
    const dirs = [{
      dir: path.join('src/app/views/'),
    }];
    dirs.forEach((dir) => {
      if (url.indexOf(dir.dir) !== -1) {
        let folder = url.substring(url.indexOf(dir.dir)).replace(dir.dir, '');
        // eslint-disable-next-line prefer-destructuring
        folder = folder.split(path.join('/'))[0];
        name = path.join(`${folder}/${name}`);
        return false;
      }
      return true;
    });
    return name;
  },
  /**
   * 构建输出文件路径
   * @param {*} file 文件
   * @param {*} type 类型：js|css
   * @returns {String}
   */
  buildFileName(file, type) {
    const names = file.chunk.name.split('/');
    const folder = names[0];
    names.shift();
    names.push('index');
    const filename = names.join('_');
    const url = `${folder}/${filename}.[contenthash:7].${type}`;
    return url;
  },
  /**
   * 处理引用链接
   * @param {*} url //资源路径
   * @returns {String}
   */
  buildPublicPath(url) {
    const paths = url.split(path.join('/'));
    paths.splice(0, 1, '.');
    url = paths.join('/');
    return url;
  },
  /**
   * 自动构建入口文件
   * @returns {Object}
   */
  buildEntry() {
    const me = this;
    // 动态读取入口
    const files = glob.sync(`./src/app/views/**/${me.entryFile}`);
    const entrys = {};
    const entry = config.entry || [];
    files.forEach((f) => {
      const name = f.replace('./src/app/views/', '').replace(`/${me.entryFile}`, '');
      if (entry.length === 0 || entry.indexOf(name.split('/')[0]) !== -1) {
        entrys[name] = f;
      }
    });
    return entrys;
  },
  /**
   * 构建html
   * @param {Object} entrys 入口
   * @returns {Array}
   */
  buildPages(entrys) {
    const me = this;
    const pages = [];
    const tpl = './config-app/template/template.html';
    const indexTpl = './config-app/template/index.html';
    // const appFolder = 'app/';
    for (const entry in entrys) {
      const _path = entrys[entry];
      const configFile = _path.replace(`/${me.entryFile}`, '/config.json');
      let _config = {};
      if (fs.existsSync(configFile)) {
        _config = JSON.parse(fs.readFileSync(configFile).toString());
      }
      _config.include = _config.include || [];
      if (_config.include.indexOf('vue') == -1) {
        _config.include.push('vue');
      }
      _config.include.push('resetcss', 'flexible');
      _config.files = _config.files || {};
      const names = entry.split('/');
      const folder = names[0];
      names.shift();
      names.push('index');
      const filename = `${folder}/${names.join('_')}.html`;

      pages.push(new HtmlWebpackPlugin({
        template: tpl,
        inject: false,
        filename,
        config: _config,
        chunks: [entry],
        minify: false, // 不压缩
        RELATIVE_ROOT: '../..', // relativeRoot.join('/'),
      }));
    }
    if (process.env.NODE_ENV === 'development') { // 开发
      pages.push(new HtmlWebpackPlugin({
        template: indexTpl,
        inject: false,
        minify: false, // 不压缩
        indexConfig: { // 首页配置信息
          entry: config.entry[0],
          username: config.username,
          password: config.password,
          proxyServerUrl: config.proxyServerUrl,
          header: config.header,
          socket: config.socket,
        },
        filename: path.resolve(__dirname, '../../', 'index.html'),
      }));
    }

    return pages;
  },
  /**
   * 生成插件包
   */
  zip() {
    const _this = this;
    const appRoot = path.resolve(__dirname, '../../', 'dist');
    const entry = config.entry || [];
    entry.forEach((fileName) => {
      // // 插件
      const pluginPath = path.join(`${appRoot}/${fileName}.zip`);
      const plugin = fs.createWriteStream(pluginPath);
      // 插件的zip包
      const pluginArchive = archiver('zip', {
        zlib: {
          level: 9,
        },
      });
      plugin.on('close', () => {
        _this.uploadUpgradeFile.call(_this, appRoot, fileName, pluginPath);
      });
      pluginArchive.pipe(plugin);
      pluginArchive.directory(path.join(`dist/${fileName}/`), false);
      pluginArchive.finalize();
    });
  },

  /**
   * 压缩正式的升级包的代码
   * @param {string} appRoot  项目入口
   * @param {*} fileName 文件名称
   * @param {*} pluginPath  插件地址
   */
  uploadUpgradeFile(appRoot, fileName, pluginPath) {
    const me = this;
    const output = fs.createWriteStream(path.join(`${appRoot}/JE-PLUGIN-${fileName.toLocaleUpperCase()}.zip`));
    output.on('close', () => {
      fs.unlink(pluginPath, (params) => {
        if (params) {
          return false;
        }
        console.log(`JE-PLUGIN-${fileName.toLocaleUpperCase()}.zip 删除成功`);
      });
      console.log(`${chalk.green(`${fileName}.zip`)} ，${(archive.pointer() / 1024 / 1024).toFixed(4)}M`);
    });
    const archive = archiver('zip', {
      zlib: {
        level: 9,
      }, // Sets the compression level.
    });
    // good practice to catch this error explicitly
    archive.on('error', (err) => {
      throw err;
    });
    // 打包插件升级包
    archive.pipe(output);
    archive.append(me.getUpgradeInfo(fileName), {
      name: 'config.json',
    });
    archive.append(fs.createReadStream(pluginPath), {
      name: 'plugin.zip',
    });
    archive.finalize();
  },

  /**
   * 驼峰转-
   * @param {String} name 驼峰命名
   * @returns {String}
   */
  toLine(name) {
    return name.replace(/([A-Z])/g, '-$1').toLowerCase();
  },

  /**
   * 获取升级包信息
   */
  getUpgradeInfo(fileName) {
    // 源码目录
    const viewPath = path.resolve(__dirname, '../../src/app/views');
    // 源码目录
    const configFilePath = path.resolve(viewPath, fileName);
    // 读取到配置文件
    const configs = JSON.parse(fs.readFileSync(`${configFilePath}/config.json`).toString());
    return JSON.stringify({
      pluginName: configs.pluginName, // 包名
      pluginCode: configs.pluginCode, // 插件名称
      describe: configs.describe, // 升级描述
      version: configs.version, // 版本信息
    });
  },
};
